extends Node2D

onready var MAIN = find_parent("MAIN")
onready var screen_diagonal = get_viewport().size.length()

export var predictor_curve : Curve
var speed = Vector2.ZERO
var MIN_RADIUS = 0.1
var accel_engine = Vector2.ZERO
var accel = Vector2.ZERO
var thrust_scale = 3200
var mouse_active = false
var gravity_constant = 1100.0

var predictor_steps = 400
var predictor_max_delta = 0.06 #seconds
var predictor

var time_flows = false
var gameover = false

var fuel = 1.0
var fuel_usage = 0.17

# Declare member variables here. Examples:
# var a = 2
# var b = "text"


# Called when the node enters the scene tree for the first time.
func _ready():
	create_predictor()
	$CAMERA.hole.visible = true
	$CAMERA/Zshifter/point_here.visible = true
	pass # Replace with function body.

func _process(delta):
	if gameover and Input.is_mouse_button_pressed(1) and $CAMERA.zoom_target == 1.0:
		get_tree().change_scene("res://MAIN.tscn")
	var normalised_mousepos = get_viewport().get_mouse_position() - get_viewport().size/2.0
	normalised_mousepos /= screen_diagonal
	if normalised_mousepos.length() < MIN_RADIUS and not gameover:
		if not mouse_active:
			MAIN.on_mouse_activate()
		mouse_active = true
		time_flows = true
		$CAMERA.hole.visible = false
		$CAMERA.idle_circle.visible = true
		$CAMERA/Zshifter/point_here.visible = false
#	print(normalised_mousepos)
#	print('polar')
	accel = Vector2.ZERO
	if time_flows:
		if mouse_active and not normalised_mousepos.length() == 0:
			$visual.rotation = cartesian2polar(normalised_mousepos.x,normalised_mousepos.y).y
			accel_engine = normalised_mousepos\
				* (1/normalised_mousepos.length()) \
				* clamp(normalised_mousepos.length()-MIN_RADIUS,0,min(get_viewport().size.x,get_viewport().size.y)) \
				* thrust_scale \
				* delta
			fuel -= accel_engine.length()/thrust_scale * fuel_usage
			if fuel <=0:
				$CAMERA/Zshifter/stranded.visible = true
				game_over()
			$visual.material.set_shader_param("full",fuel)
			accel += accel_engine
			$visual/fire.visible = accel_engine != Vector2.ZERO
			var fire_length = accel_engine.length()/thrust_scale*180
			#print (fire_length)
			$visual/fire.scale.x = 0.1 + fire_length 
			#print(accel)
		var gravity = integrate_gravities()
		if typeof(gravity) == TYPE_VECTOR2:
			accel += gravity
			speed += accel*delta
			update_predictor(delta*8.0)
			position += speed*delta
		else:
			$CAMERA/Zshifter/lithobroken.visible = true
			game_over()

func game_over():
	gameover = true
	time_flows = false
	$CAMERA.hole.visible = true
	$CAMERA.idle_circle.visible = false
	find_parent("MAIN").timer.stop()
	for p in MAIN.planets:
		p.finish_jam()

func create_predictor():
	predictor = Line2D.new()
	var curve = Curve.new()
	curve.min_value = 0.0
	curve.max_value = 1.0
	curve.bake()
	predictor.width_curve = predictor_curve
	predictor.width = 4 
	add_child(predictor)

func update_predictor(delta):
	var p_speed = speed
	var p_accel = accel - accel_engine
	var p_pos = Vector2.ZERO
	var points = PoolVector2Array()
#	var delta = predictor_max_delta
	
	points.append(p_pos)
	for i in range(predictor_steps):
		p_pos += p_speed * delta
		p_accel = field_in_globalpos(global_position + p_pos)
		if typeof(p_accel) != TYPE_VECTOR2:
			break
		p_speed += p_accel * delta
		points.append(p_pos)
	predictor.points = points
	#print(predictor.points)

func field_in_globalpos(globalpos):
	var gravity = Vector2.ZERO
	for p in MAIN.planets:
		var dist = p.global_position - globalpos
		if dist.length() <= p.radius:
			return -1
		gravity += p.mass*gravity_constant*dist/pow(dist.length(),3)
	return gravity

func integrate_gravities():
	return field_in_globalpos(global_position)
	

# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#	pass
